﻿//#define _CRT_SECURE_NO_WARNINGS
//#include <stdio.h>
#include "common.h"

// 刷题可以去 leetcode 刷，也可以去牛客网刷，或者去 C 语言中文网刷。

/*
结构体语法：
struct 结构体名称
{
    数据类型 成员名;
    数据类型 成员名;
   ...
} 变量名1, 变量名2,..., 变量名n; // 变量名为结构体变量名（可有可无）
    // 结构体变量名可以有多个，每个变量名之间用逗号隔开

结构体声明：
    struct 结构体名称 变量名; // 声明结构体变量（注意变量的生命周期）

结构体初始化：
    结构体变量名 = {成员1值, 成员2值,..., 成员n值}; // 初始化结构体变量
    注意全局变量不初始化的时候，默认初始化为 0 （静态区）
    局部变量不初始化，默认初始化为随机值，VS 中初始化为 0x cccccccc （栈区）

结构体访问：
    结构体变量名.成员名; // 访问结构体成员
    结构体指针变量名->成员名; // 访问结构体成员（指针方式）

结构体变量名：
    结构体变量名就是结构体的别名，可以用来表示一个结构体变量。
    结构体变量名是利用结构体的名称来定义和创建的，可以用来引用结构体的成员。

结构体成员：
    结构体成员就是结构体的属性，可以包含不同的数据类型。
    结构体成员可以是基本数据类型，也可以是结构体（结构体嵌套），数组，指针等。


*/

// 定义结构体
struct Person
{
    char name[20];
    int age;
    char gender[5];
} person1, person2; // 声明结构体变量，这里为全局变量

// 结构体嵌套
struct Student
{
    struct Person person; // 结构体嵌套
    char address[200];
    float score;
    char title[50];
} student1, student2; // 声明结构体变量，这里为全局变量

int main()
{
    // 结构体变量初始化、结构体成员访问
    {
        print_start_line("结构体变量初始化、结构体成员访问测试开始");
        printf("Person的大小为：%zd\n", sizeof(struct Person));
        /*printf("Student1.address的大小为：%zd\n",
            sizeof(Student1.address)); // err：不能计算结构体成员的大小*/
        struct Person p1 = { "Tom", 20, "Male" };
        struct Person p2 = { "486", 20, "男" };

        struct Student st1 = { p1, "Shanghai", 90.5f, "Master" };
        struct Student st2 = {
            {"八一", 20, "男"}, "二次元", 66.6f, "牢饭专家" };

        printf("p1: name=%s, age=%d, gender=%s\n",
            p1.name, p1.age, p1.gender);
        printf("st1: name=%s, age=%d, gender=%s, address=%s, score=%.1f, title=%s\n",
            st1.person.name, st1.person.age, st1.person.gender,
            st1.address, st1.score, st1.title);

        // 结构体成员访问：指针形式
        struct Person* pp2 = &p2;
        printf("p2: name=%s, age=%d, gender=%s\n",
            pp2->name, pp2->age, pp2->gender);
        printf("p2: name=%s, age=%d, gender=%s\n",
            (*pp2).name, (*pp2).age, (*pp2).gender); // 同上
        // 注意这里必须带括号，因为 . 运算符优先级比 * 高
        struct Student* pst2 = &st2;
        printf("pst2: name=%s, age=%d, gender=%s，address=%s, score=%.1f, title=%s\n",
            pst2->person.name, pst2->person.age, pst2->person.gender,
            pst2->address, pst2->score, pst2->title);

        print_end_line("结构体变量初始化、结构体成员访问测试结束");
    }

    // 结构体作业部分
    {
        print_start_line("结构体作业部分开始");
        // a、b、c的值分别是什么？
        selection_2();

        // 求两个整数的二进制数的不同位数
        printf("1999 和 2299 的二进制数的不同位数的个数是：%d\n",
            different_0x(1999, 2299));

        // sizeof 操作符比较测试
        sizeof_compare_test();

        // 输入行数，打印输出 x 图案
        print_x(6);

        // 结构体指针数组测试
        structure_pointer_test();

        print_end_line("结构体作业部分结束");
    }

    return 0;
}
